﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace CopyPathFile
{
    public delegate void SearchHandler(CopyFile file);
    public delegate void ErrorHandler(string msg, CopyFile file);
    public delegate void CompleteHandler();
    public delegate void CopyHandler(CopyFile file);
    public class CopyPath
    {
        public event SearchHandler OnSearch;
        public event ErrorHandler OnError;
        public event CopyHandler OnCopy;
        public event EventHandler OnSearchEnd;
        public event CompleteHandler OnComplete;

        private string _TargetPath;
        public string TargetPath
        {
            get { return _TargetPath; }
            set
            {
                if (value.EndsWith("\\"))
                {
                    _TargetPath = value;
                }
                else
                {
                    _TargetPath = value + "\\";
                }
            }
        }

        private string _SourcePath;
        public string SourcePath
        {
            get { return _SourcePath; }
            set
            {
                if (value.EndsWith("\\"))
                {
                    _SourcePath = value;
                }
                else
                {
                    _SourcePath = value + "\\";
                }
            }
        }

        public string[] Filter
        {
            get;
            set;
        }

        public List<CopyFile> AllFiles = new List<CopyFile>();
        public List<string> AllPaths = new List<string>();

        public void DoCopy()
        {
            if (AllFiles.Count < 1)
            {
                Search();
            }
            foreach (CopyFile file in AllFiles)
            {
                if (OnCopy != null)
                {
                    OnCopy(file);
                }
                string targetPath = System.IO.Path.GetDirectoryName(file.Target);
                try
                {
                    if (!Directory.Exists(targetPath))
                    {
                        Directory.CreateDirectory(targetPath);
                    }
                    if (File.Exists(file.Target))
                    {
                        File.SetAttributes(file.Target, FileAttributes.Normal);
                    }
                    File.Copy(file.Source, file.Target, true);
                }
                catch (Exception ex) {

                    if (OnError != null)
                    {
                        OnError(ex.Message,file);
                    }
                }
            }
            if (OnComplete != null)
            {
                OnComplete();
            }
        }

        public void DoCopy(string targetPath, string sourcePath, string[] filter)
        {
            this.TargetPath = targetPath;
            this.SourcePath = sourcePath;
            this.Filter = filter;
            DoCopy();
        }

        public void Search()
        {
            AllFiles.Clear();
            AllPaths.Clear();
            DirSearch(SourcePath);
            if (OnSearchEnd != null)
            {
                OnSearchEnd(this, EventArgs.Empty);
            }
        }

        private void DirSearch(string sDir)
        {
            
                foreach (string filter in Filter)
                {
                    foreach (string f in Directory.GetFiles(sDir, filter, SearchOption.TopDirectoryOnly))
                    {
                        CopyFile file = new CopyFile(f, GetFileTarget(f));
                        AllFiles.Add(file);
                        if (OnSearch != null)
                        {
                            OnSearch(file);
                        }
                    }
                }
                foreach (string d in Directory.GetDirectories(sDir))
                {
                    AllPaths.Add(d);
                    DirSearch(d);
                }
            
            
        }

        private string GetFileTarget(string sourceFilePath)
        {
            return TargetPath + sourceFilePath.Substring(SourcePath.Length);
        }
    }

    public class CopyFile
    {
        public CopyFile(string source, string target)
        {
            this.Source = source;
            this.Target = target;

        }
        public string Source { get; set; }
        public string Target { get; set; }
    }
}
